/*
 * SystemSignal.h
 *
 *  Created on: May 16, 2013
 *      Author: yuliang
 */

#ifndef SYSTEMSIGNAL_H_
#define SYSTEMSIGNAL_H_

#include <signal.h>
#include <map>
#include <stdint.h>

#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>

#define LOGBUFLEN 1024
#define USER_SIG _NSIG + 1
#define PRO_FILE_NAME "ProcessName.log"
#define SIGNAL_ERROR_LOG "SignalLog.log"

class UsrSignalBase;
typedef int32_t Signal_t;
typedef std::map<Signal_t, UsrSignalBase*> Map_UserSig;

const Signal_t CSignalFlag[] = {
		SIGINT,		// ctrl + c
		SIGSEGV,	// 无效内存引用
		SIGFPE,		// 浮点异常
		SIGPIPE		// 管道破裂
};

/*
 * 用户信号基类
 */
class UsrSignalBase {
	friend class CSystemSignal;
public:
	UsrSignalBase(Signal_t uSig = USER_SIG) : m_UsrSignal(uSig){}
	virtual ~UsrSignalBase(){}
	// 捕捉用户信号
	virtual void CatchUsrSignal();
private:
	Signal_t m_UsrSignal;
};

/*
 * 捕捉系统信号和用户信号类
 */
class CSystemSignal {
public:
	virtual ~CSystemSignal();
	/*
	 * 单例模式
	 * bAnalysis :是否解析错误内存地址,当前进程下的目录存在进程程序选择默认true；
	 *            后台运行或者fork的进程选择false(暂不支持false)
	 */
	static CSystemSignal* Getinstance(bool bAnalysis = true);
	// 添加用户信号
	void AddUserSignal(UsrSignalBase *pUserSignal);
	/*
	 * 开始捕捉
	 * 用户信号添加之后调用
	 */
	void StartCatch() const;
protected:
	CSystemSignal(bool bAnalysis = true);
	// 设置捕捉信号
	static void CatchSomeSignal(int iSigNum);
private:
	// 设置一个信号
	void SetOneSignal(Signal_t iSig) const;

	// 处理系统内存错误信号
	void SegmentFault() const;
	// 输出内存错误日志
	bool PrintSegvInfo(const char *pcSegvInfo, const char *pcProName) const;

	// 获取当前进程名称
	bool GetLocalProcessName(char *pcBuf, int iBufLen) const;
private:
	static CSystemSignal* instance;
	Map_UserSig m_mUserSig;
	bool m_bAnalysis;
};

#endif /* SYSTEMSIGNAL_H_ */
